package com.demo.generate.code;

import com.demo.generate.code.config.CodeGeneratorConfig;
import com.demo.generate.code.service.CodeGeneratorService;
import com.demo.generate.code.service.TableInfoService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.util.StringUtils;

import java.sql.SQLException;
import java.util.Arrays;

/**
 * 代码生成器主启动类
 */
@SpringBootApplication(exclude = {
        org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class,
        org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class
})
@EnableConfigurationProperties({CodeGeneratorConfig.class})
public class CodeGeneratorApplication {

    public static void main(String[] args) {
        // 直接运行代码生成逻辑，不启动Web服务器
        ConfigurableApplicationContext context = SpringApplication.run(CodeGeneratorApplication.class, args);

        // 检查必要的配置是否存在
        CodeGeneratorConfig config = context.getBean(CodeGeneratorConfig.class);
        if (!isDatabaseConfigValid(config)) {
            System.err.println("错误: 数据库配置不完整，请在配置文件中设置以下属性:");
            System.err.println("- code.generator.database.url");
            System.err.println("- code.generator.database.username");
            System.err.println("- code.generator.database.password");
            System.err.println("- code.generator.database.driver-class-name");
            System.err.println("");
            System.err.println("示例配置:");
            System.err.println("code:");
            System.err.println("  generator:");
            System.err.println("    database:");
            System.err.println("      url: jdbc:mysql://localhost:3306/your_database");
            System.err.println("      username: your_username");
            System.err.println("      password: your_password");
            System.err.println("      driver-class-name: com.mysql.cj.jdbc.Driver");
            System.err.println("    generator:");
            System.err.println("      base-package: com.example.project");
            System.err.println("      output-dir: ./generated-code");
            context.close();
            return;
        }

        if (!isGeneratorConfigValid(config)) {
            System.err.println("错误: 生成器配置不完整，请在配置文件中设置以下属性:");
            System.err.println("- code.generator.generator.base-package");
            context.close();
            return;
        }

        if (args.length > 0) {
            try {
                TableInfoService tableInfoService = context.getBean(TableInfoService.class);
                CodeGeneratorService codeGeneratorService = context.getBean(CodeGeneratorService.class);

                if ("all".equalsIgnoreCase(args[0])) {
                    // 生成所有表的代码
                    try {
                        tableInfoService.getTableNames().forEach(tableName -> {
                            try {
                                System.out.println("正在生成表 [" + tableName + "] 的代码...");
                                codeGeneratorService.generateCode(tableName);
                            } catch (Exception e) {
                                System.err.println("生成表 [" + tableName + "] 的代码时发生异常: " + e.getMessage());
                                e.printStackTrace();
                            }
                        });
                    } catch (SQLException e) {
                        System.err.println("获取表名列表失败: " + e.getMessage());
                        e.printStackTrace();
                    }
                } else {
                    // 生成指定表的代码
                    Arrays.stream(args).forEach(tableName -> {
                        try {
                            System.out.println("正在生成表 [" + tableName + "] 的代码...");
                            codeGeneratorService.generateCode(tableName);
                        } catch (Exception e) {
                            System.err.println("生成表 [" + tableName + "] 的代码时发生异常: " + e.getMessage());
                            e.printStackTrace();
                        }
                    });
                }

                System.out.println("代码生成完成!");
            } finally {
                context.close();
            }
        }
    }

    /**
     * 检查数据库配置是否有效
     * @param config 配置对象
     * @return 是否有效
     */
    private static boolean isDatabaseConfigValid(CodeGeneratorConfig config) {
        CodeGeneratorConfig.Database database = config.getDatabase();
        return database != null &&
                StringUtils.hasText(database.getUrl()) &&
                StringUtils.hasText(database.getUsername()) &&
                StringUtils.hasText(database.getPassword()) &&
                StringUtils.hasText(database.getDriverClassName());
    }

    /**
     * 检查生成器配置是否有效
     * @param config 配置对象
     * @return 是否有效
     */
    private static boolean isGeneratorConfigValid(CodeGeneratorConfig config) {
        CodeGeneratorConfig.Generator generator = config.getGenerator();
        return generator != null && StringUtils.hasText(generator.getBasePackage());
    }

    @Bean
    public CommandLineRunner commandLineRunner(TableInfoService tableInfoService, CodeGeneratorService codeGeneratorService) {
        return args -> {
            // 当没有命令行参数时，显示帮助信息
            if (args.length == 0) {
                System.out.println("请指定要生成代码的表名");
                System.out.println("使用方法: java -jar generator.jar tableName [tableName2] ...");
                System.out.println("或者使用 'all' 生成所有表的代码");
                System.out.println("");
                System.out.println("注意: 必须提供数据库连接配置和基本包名配置");
                System.out.println("请参考README.md了解详细配置说明");
            }
        };
    }
}